﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestByWire.Factories.StubbingStrategies;

namespace TestByWire.Test.Factories.StubbingStrategies
{
	[TestClass]
	public class StubStrategyBaseTest
	{
		private StubStrategyBaseInTest _stubStrategyBase;

		[TestInitialize]
		public void PerTestSetup()
		{
			_stubStrategyBase = new StubStrategyBaseInTest();
		}

		[TestMethod]
		public void CreateInstance_MustThrow_WhenTypeIsNull()
		{
			var exception = AssertEx.Throws<ArgumentNullException>(() => _stubStrategyBase.CreateInstance(null, "Foo"));

			Assert.AreEqual("type", exception.ParamName);
		}

		[TestMethod]
		public void CreateInstance_MustThrow_IfStubStrategyCannotHandleType()
		{
			_stubStrategyBase.CanHandleTypeFlag = false;

			var exception = AssertEx.Throws<InvalidOperationException>(() => _stubStrategyBase.CreateInstance(typeof(string), "Foo"));

			Assert.AreEqual("Provided type can not be handled by stub strategy.", exception.Message);
		}

		internal class StubStrategyBaseInTest : StubStrategyBase
		{
			public StubStrategyBaseInTest()
			{
				CanHandleTypeFlag = true;
			}

			protected bool TryCreateInstanceWasCalled { get; private set; }

			public bool CanHandleTypeFlag { get; set; }

			public override bool RegisterOnContainer
			{
				get { return true; }
			}

			public override bool CanHandleType(Type type, string instanceName)
			{
				return CanHandleTypeFlag;
			}

			protected override object TryCreateInstance(Type type)
			{
				TryCreateInstanceWasCalled = true;

				return null;
			}
		}
	}
}
